const app = getApp();
import { Config } from '../../utils/config.js';
/**
 * 判断是否超出范围
 */
const IsOutRange = (x1, y1, x2, y2, x3, y3) => {
  return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3
};

/**
 * 版本号比较
 */
const compareVersion = (v1, v2) => {
  v1 = v1.split('.')
  v2 = v2.split('.')
  const len = Math.max(v1.length, v2.length)

  while (v1.length < len) {
    v1.push('0')
  }
  while (v2.length < len) {
    v2.push('0')
  }

  for (let i = 0; i < len; i++) {
    const num1 = parseInt(v1[i])
    const num2 = parseInt(v2[i])

    if (num1 > num2) {
      return 1
    } else if (num1 < num2) {
      return -1
    }
  }

  return 0
}
Component({
  options: {
    multipleSlots: true
  },
  properties: {
    extraNodes: { type: Array, value: [] },                  // 额外节点
    listData: { type: Array, value: [] },                    // 数据源
    maxCount : {type: Number, value: 1},                      //最多上传图片数
    columns: { type: Number, value: 1 },                     // 列数
    topSize: { type: Number, value: 0 },                     // 顶部高度
    bottomSize: { type: Number, value: 0 },                  // 底部高度
    scrollTop: { type: Number, value: 0 }                    // 页面滚动高度
  },
  data: {
    /* 未渲染数据 */
    pageMetaSupport: false,                                 // 当前版本是否支持 page-meta 标签
    windowHeight: 0,                                        // 视窗高度
    platform: '',                                           // 平台信息
    realTopSize: 0,                                         // 计算后顶部固定高度实际值
    realBottomSize: 0,                                      // 计算后底部固定高度实际值
    rows: 0,                                                // 行数
    itemDom: { width: 0, height: 0, left: 0, top: 0 },        // 每一项 item 的 dom 信息, 由于大小一样所以只存储一个
    itemWrapDom: { width: 0, height: 0, left: 0, top: 0 },    // 整个拖拽区域的 dom 信息
    startId: 0,                                             // 初始触摸点 identifier
    preStartKey: -1,                                        // 前一次排序时候的起始 sortKey 值

    /* 渲染数据 */
    list: [],                                               // 渲染数据列
    cur: -1,                                                // 当前激活的元素
    curZ: -1,                                               // 当前激活的元素, 用于控制激活元素z轴显示
    tranX: 0,                                               // 当前激活元素的 X轴 偏移量
    tranY: 0,                                               // 当前激活元素的 Y轴 偏移量
    itemWrapHeight: 0,                                      // 动态计算父级元素高度
    dragging: false,                                        // 是否在拖拽中
    itemTransition: false,                                  // item 变换是否需要过渡动画, 首次渲染不需要

  },

  ready: function () {
    var that = this;
    wx.getSystemInfo({
      success: res => {
        that.setData({
          screenWidth: res.screenWidth
        })
      }
    })
  },
  methods: {
    
    /**
		 * 长按触发移动排序
		 */
    longPress(e) {
      
      // 获取触摸点信息
      let startTouch = e.changedTouches[0];
      if (!startTouch) return;
      // 固定项则返回
      let index = e.currentTarget.dataset.index;
      if (this.isFixed(index)) return;
      // 防止多指触发 drag 动作, 如果已经在 drag 中则返回, touchstart 事件中有效果
      if (this.data.dragging) return;
      this.setData({ dragging: true });
     
      let { platform, itemDom, itemWrapDom } = this.data,
        { pageX: startPageX, pageY: startPageY, identifier: startId } = startTouch;

      // 计算X,Y轴初始位移, 使 item 中心移动到点击处
      let tranX = startPageX - itemDom.width / 2 - itemWrapDom.left,
        tranY = startPageY - itemDom.height / 2 - itemWrapDom.top;
      // 单列时候X轴初始不做位移
      if (this.data.columns === 1) tranX = 0;

      this.data.startId = startId;
      this.setData({ cur: index, curZ: index, tranX, tranY });

      if (platform !== "devtools") wx.vibrateShort();
    },
    touchMove(e) {
      // 获取触摸点信息
      let currentTouch = e.changedTouches[0];
      if (!currentTouch) return;

      if (!this.data.dragging) return;

      let { pageMetaSupport, windowHeight, realTopSize, realBottomSize, itemDom, itemWrapDom, preStartKey, columns, rows } = this.data,
        { pageX: currentPageX, pageY: currentPageY, identifier: currentId, clientY: currentClientY } = currentTouch;

      // 如果不是同一个触发点则返回
      if (this.data.startId !== currentId) return;

      // 通过 当前坐标点, 初始坐标点, 初始偏移量 来计算当前偏移量
      let tranX = currentPageX - itemDom.width / 2 - itemWrapDom.left,
        tranY = currentPageY - itemDom.height / 2 - itemWrapDom.top;
      // 单列时候X轴初始不做位移
      if (columns === 1) tranX = 0;

      // 到顶到底自动滑动
      if (currentClientY > windowHeight - itemDom.height - realBottomSize) {
        // 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度)

        if (pageMetaSupport) {
          this.triggerEvent("scroll", {
            scrollTop: currentPageY + itemDom.height - (windowHeight - realBottomSize)
          });
        } else {
          wx.pageScrollTo({
            scrollTop: currentPageY + itemDom.height - (windowHeight - realBottomSize),
            duration: 300
          });
        }
      } else if (currentClientY < itemDom.height + realTopSize) {
        // 当前触摸点pageY - item高度 - 顶部固定区域高度

        if (pageMetaSupport) {
          this.triggerEvent("scroll", {
            scrollTop: currentPageY - itemDom.height - realTopSize
          });
        } else {
          wx.pageScrollTo({
            scrollTop: currentPageY - itemDom.height - realTopSize,
            duration: 300
          });
        }
      }

      // 设置当前激活元素偏移量
      this.setData({ tranX: tranX, tranY: tranY });

      // 获取 startKey 和 endKey
      let startKey = parseInt(e.currentTarget.dataset.key);
      let curX = Math.round(tranX / itemDom.width), curY = Math.round(tranY / itemDom.height);
      let endKey = curX + columns * curY;

      // 遇到固定项和超出范围则返回
      if (this.isFixed(endKey) || IsOutRange(curX, columns, curY, rows, endKey, this.data.list.length)) return;

      // 防止拖拽过程中发生乱序问题
      if (startKey === endKey || startKey === preStartKey) return;
      this.data.preStartKey = startKey;

      // 触发排序
      this.sort(startKey, endKey);
    },
    touchEnd() {
      if (!this.data.dragging) return;
      this.triggerCustomEvent(this.data.list, "sortend");
      this.clearData();
    },
		/**
		 * 根据 startKey 和 endKey 去重新计算每一项 sortKey
		 */
    sort(startKey, endKey) {
      this.setData({ itemTransition: true });
      let list = this.data.list.map((item) => {
        if (item.fixed) return item;
        if (startKey < endKey) { // 正序拖动
          if (item.sortKey > startKey && item.sortKey <= endKey) {
            item.sortKey = this.excludeFix(item.sortKey - 1, startKey, 'reduce');
          } else if (item.sortKey === startKey) {
            item.sortKey = endKey;
          }
          return item;
        } else if (startKey > endKey) { // 倒序拖动
          if (item.sortKey >= endKey && item.sortKey < startKey) {
            item.sortKey = this.excludeFix(item.sortKey + 1, startKey, 'add');
          } else if (item.sortKey === startKey) {
            item.sortKey = endKey;
          }
          return item;
        }
      });
      this.updateList(list);
    },
		/**
		 * 排除固定项得到最终 sortKey
		 */
    excludeFix(sortKey, startKey, type) {
      if (sortKey === startKey) return startKey;
      if (this.data.list[sortKey].fixed) {
        let _sortKey = type === 'reduce' ? sortKey - 1 : sortKey + 1;
        return this.excludeFix(_sortKey, startKey, type);
      } else {
        return sortKey;
      }
    },
		/**
		 * 根据排序后 list 数据进行位移计算
		 */
    updateList(data, vibrate = true) {
      let { platform } = this.data;

      let list = data.map((item, index) => {
        item.tranX = `${(item.sortKey % this.data.columns) * 100}%`;
        item.tranY = `${Math.floor(item.sortKey / this.data.columns) * 100}%`;
        return item;
      });
      this.setData({ list: list });

      if (!vibrate) return;
      if (platform !== "devtools") wx.vibrateShort();

      this.triggerCustomEvent(list, "change");
    },
		/**
		 * 判断是否是固定的 item
		 */
    isFixed(index) {
      let list = this.data.list;
      if (list && list[index] && list[index].fixed) return true;
      return false;
    },
		/**
		 * 清除参数
		 */
    clearData() {
      this.setData({
        preStartKey: -1,
        dragging: false,
        cur: -1,
        tranX: 0,
        tranY: 0
      });
      // 延迟清空
      setTimeout(() => {
        this.setData({
          curZ: -1,
        })
      }, 300)
    },
		/**
		 * 点击每一项后触发事件
		 */
    itemClick(e) {
      let { index, key } = e.currentTarget.dataset;
      let list = this.data.list;
      let currentItem = list[index];

      if (!currentItem.extraNode) {
        let _list = [];

        list.forEach((item) => {
          _list[item.sortKey] = item;
        });

        let currentKey = -1;

        for (let i = 0, len = _list.length; i < len; i++) {
          let item = _list[i];
          if (!item.extraNode) {
            currentKey++;
          }
          if (item.sortKey === currentItem.sortKey) {
            break;
          }
        }

        this.triggerEvent('click', {
          key: currentKey,
          data: currentItem.data
        });
      }
    },
		/**
		 * 封装自定义事件
		 * @param list 当前渲染的数据
		 * @param type 事件类型
		 */
    triggerCustomEvent(list, type) {
      let _list = [];
      list.forEach((item) => {
        _list[item.sortKey] = item;
      });

      this.triggerEvent(type, { listData: _list });
    },
		/**
		 *  初始化获取 dom 信息
		 */
    initDom() {
      let { windowWidth, windowHeight, platform, SDKVersion } = wx.getSystemInfoSync();

      this.data.pageMetaSupport = compareVersion(SDKVersion, '2.9.0') >= 0;

      let remScale = (windowWidth || 375) / 375,
        realTopSize = this.data.topSize * remScale / 2,
        realBottomSize = this.data.bottomSize * remScale / 2;

      this.data.windowHeight = windowHeight;
      this.data.platform = platform;
      this.data.realTopSize = realTopSize;
      this.data.realBottomSize = realBottomSize;

      this.createSelectorQuery().select(".item").boundingClientRect((res) => {
        let rows = Math.ceil(this.data.list.length / this.data.columns);

        this.data.rows = rows;
        this.data.itemDom = res;
        this.setData({
          itemWrapHeight: rows * res.height,
        });

        this.createSelectorQuery().select(".item-wrap").boundingClientRect((res) => {
          this.data.itemWrapDom = res;
          this.data.itemWrapDom.top += this.data.scrollTop
        }).exec();
      }).exec();
    },
		/**
		 *  初始化函数
		 *  {listData, columns, topSize, bottomSize} 参数改变需要重新调用初始化方法
     *  editData 编辑数据，在编辑内容的时候由父组件传递过来
		 */
    init(editData = []) {
      //自定义编辑业务逻辑
      if(editData.length > 0){
        var diyListData = [];
        var diyList = [];
        editData.forEach((item,index)=>{
          diyListData.push(item.thumbImg);
        })
        this.setData({
          listData : diyListData,
          list : editData
        })
      }
      //编辑结束

      this.clearData();
      this.setData({ itemTransition: false});

      let delItem = (item, extraNode) => ({
        id: item.dragId,
        slot: item.slot,
        fixed: false,
        extraNode: extraNode,
        tranX: "0%",
        tranY: "0%",
        data: item
      });
      let { listData, extraNodes } = this.data;
      let _list = [], _before = [], _after = [], destBefore = [], destAfter = [];

      extraNodes.forEach((item, index) => {
        if (item.type === "before") {
          _before.push(delItem(item, true));
        } else if (item.type === "after") {
          _after.push(delItem(item, true));
        } else if (item.type === "destBefore") {
          destBefore.push(delItem(item, true));
        } else if (item.type === "destAfter") {
          destAfter.push(delItem(item, true));
        }
      });
      var top = listData.length / 4;
      top = parseInt(top) * 100;
      this.setData({
        'addTranLeft': (listData.length % 4) * 100,
        'addTranTop': top
      })
      // 遍历数据源增加扩展项, 以用作排序使用
      
      listData.forEach((item, index) => {
        destBefore.forEach((i) => {
          if (i.data.destKey === index) _list.push(i);
        });
        _list.push(delItem(item, false));
        //加入自定义字段
        var len = this.data.list.length;
        if(len > 0  && index < len){
          _list[index].url = this.data.list[index].url;
          _list[index].thumbImg = this.data.list[index].thumbImg;
        }
        
        //
        destAfter.forEach((i) => {
          if (i.data.destKey === index) _list.push(i);
        });
      });
      
      let list = _before.concat(_list, _after).map((item, index) => {
        item.sortKey = index; // 初始化 sortKey 为当前项索引值
        item.tranX = `${(item.sortKey % this.data.columns) * 100}%`;
        item.tranY = `${Math.floor(item.sortKey / this.data.columns) * 100}%`;
        return item;
      });

      if (list.length === 0) {
        this.setData({ itemWrapHeight: 0 });
        return;
      }
      this.updateList(list, false);
      // 异步加载数据时候, 延迟执行 initDom 方法, 防止基础库 2.7.1 版本及以下无法正确获取 dom 信息
      setTimeout(() => this.initDom(), 0);
    },
    //删除指定图片,绑定时用catchtap 防止冒泡
    delete:function(e){
      var that = this;
      var index = e.currentTarget.dataset.index;
      this.data.listData.splice(index, 1);
      this.data.list.splice(index, 1);
      this.init();
      that.triggerCustomEvent(that.data.list, 'upload');
    },
    chooseImage: function (e) {
      var that = this;
      var url = Config.restUrl;
      url = url.slice(0, url.length - 4);
      var listLen = this.data.list.length;
      var max = that.data.maxCount - listLen;
      wx.chooseImage({
        sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
        sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有
        count: max,
        success: function (res) {
          // 返回选定照片的本地文件路径列表，tempFilePath可以作为img标签的src属性显示图片
          that.setData({
            listData: that.data.listData.concat(res.tempFilePaths)
          });
          that.init();
          var success = 0;
          var len = res.tempFilePaths.length;
          for(var i = 0; i< len;i++){
            wx.uploadFile({
              url: url + '/upload/images-upload?fileparam=image&thumb=1&width=100&height=100&index='+i,
              filePath: res.tempFilePaths[i],
              name: 'image',
              formData: {
              },
              success: function (res) {
                var data = JSON.parse(res.data);
                if(data.files){
                  success++;
                  var index = data.files[0].index;
                  index = parseInt(listLen) + parseInt(index);
                  var url = data.files[0].url;
                  that.data.list[index].status = 1;
                  that.data.list[index].url= url;
                  that.data.list[index].thumbImg = data.files[0].thumbImg;
                  if(success == len){
                    that.triggerCustomEvent(that.data.list, 'upload');
                  }
                }else{
                  that.data.list[index].status = 0;
                }

              }
            })
          }

        }
      })
    },
    previewImage: function (e) {
      wx.previewImage({
        current: e.currentTarget.id, // 当前显示图片的http链接
        urls: this.data.files // 需要预览的图片http链接列表
      })
    },
  }
})